package com.csxy.news.util;

import java.io.InputStream;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Pattern;

/**
 * 数据库操作类
 * 
 * @author hp
 *
 */
public class JdbcUtil {

	private static String leftVoidChar = "";
	private static String rightVoidChar = "";

	private static String driver = "com.mysql.jdbc.Driver";
	private static String url = "jdbc:mysql://127.0.0.1:3306/vote?useUnicode=true&characterEncoding=utf8&useSSL=false";
	private static String user = "root";
	private static String password = "";

	// 连接对象
	private static Connection conn;

	static {
		try {
			// 从资源中加载连接参数
			InputStream is = JdbcUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
			Properties p = new Properties();
			p.load(is);
			driver = p.getProperty("driver", driver);
			if (driver.contains("mysql")) {
				leftVoidChar = "`";
				rightVoidChar = "`";
			} else if (driver.contains("sqlserver")) {
				leftVoidChar = "[";
				rightVoidChar = "]";
			} else if (driver.contains("oracle")) {
				leftVoidChar = "`";
				rightVoidChar = "`";
			}
			url = p.getProperty("url", url);
			user = p.getProperty("user", user);
			password = p.getProperty("password", password);
			// 加载驱动类到内存（JVM）
			Class.forName(driver);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 打开连接对象
	 * 
	 * @return
	 * @throws SQLException
	 */
	public static Connection openConnection() throws SQLException {
		conn = DriverManager.getConnection(url, user, password);
		return conn;
	}

	// 关闭连接对象
	public static void closeConnection() {

		if (conn == null) {
			return;
		}
		try {
			if (!conn.isClosed()) {
				conn.close();
				conn = null;
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 执行除查询外的其它SQL语句
	 * 
	 * @param sql
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public static boolean execute(String sql, Object... params) throws Exception {

		PreparedStatement pstmt = conn.prepareStatement(sql);

		for (int i = 0; i < params.length; i++) {
			pstmt.setObject(i + 1, params[i]);
		}

		conn.setAutoCommit(false);

		boolean b = pstmt.execute();
		try {
			conn.commit();
		} catch (Exception e) {
			conn.rollback();
			b = false;
		} finally {
			pstmt.close();
			conn.setAutoCommit(true);
		}
		return b;

	}

	/**
	 * 插入记录，并返回插入记录的id号（自动递增的字段）
	 * @param sql
	 * @param params
	 * @return last_insert_id
	 * @throws Exception
	 */
	public static Integer insert(String sql, Object... params) throws Exception {
		assert (null != sql && !"".equals(sql)) : "SQL不能为空";
		// 判断连接对象是否有效
		if (null == conn || conn.isClosed()) {
			throw new Exception("连接对象不能为空且不能关闭");
		}
		
		Integer id=null;

		Pattern p = Pattern.compile("^(insert|INSERT) .*$");
		boolean b = p.matcher(sql.trim()).find();
		if (b) {
			conn.setAutoCommit(false);
			// 获取语句对象
			PreparedStatement pstmt = conn.prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				pstmt.setObject(i + 1, params[i]);
			}
			int ret = pstmt.executeUpdate();
			b = ret > 0;
			if(b){
				//获取插入记录的id号
				sql="SELECT LAST_INSERT_ID() id";
			    Statement stmt=conn.createStatement();
				ResultSet rs=stmt.executeQuery(sql);
			    if(rs.next()){
			       id=rs.getInt("id");
			    }
			    rs.close();
			    stmt.close();
				
			}
			try {
				conn.commit();
			} catch (Exception e) {
				conn.rollback();
				id=null;
			} finally {
				pstmt.close();
				conn.setAutoCommit(true);
			}

		}
		
		return id;

	}

	/**
	 * 将一个对象所包含的数据插入到表中：对象数据--->行
	 * 
	 * @param object
	 *            约定： 1、对象的getXxx的Xxx写小xxx对应数据表的列名称 2、对象的id对象表的主键列
	 * @param tables
	 * @return
	 * @throws InvocationTargetException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws SQLException
	 */
	public static boolean insert(Object object, String... tables) throws Exception {
		assert (null != object) : "对象不能为空";

		// 判断连接对象是否有效
		if (null == conn || conn.isClosed()) {
			throw new Exception("连接对象不能为空且不能关闭");
		}

		Class<?> clazz = object.getClass();
		// 确定插入的表的名称
		String table = tables.length > 0 ? tables[0] : clazz.getSimpleName();
		// 通过反射类获取所有的getXxx方法（不包括父类的getXxx方法）
		Method[] methods = ReflectUtil.findGetMethods(clazz, "getId");
		// 获取字段-非空值的映射
		Map<String, Object> field2NotNullValueMap = new HashMap<String, Object>();
		for (Method method : methods) {
			// 变成小写开头
			Object value = method.invoke(object);
			if (null != value) {
				String field = StringUtil.toLowerFirstChar(method.getName().substring(3));// 除去get
				field2NotNullValueMap.put(field, value);
			}
		}
		// 构建SQL的insert语句
		StringBuilder sb = new StringBuilder();
		sb.append("insert into ").append(leftVoidChar).append(table).append(rightVoidChar).append("( ");
		for (Map.Entry<String, Object> entry : field2NotNullValueMap.entrySet()) {
			String field = entry.getKey();
			sb.append(leftVoidChar).append(field).append(rightVoidChar).append(",");
		}

		sb.deleteCharAt(sb.length() - 1);
		// sb.replace(sb.length()-1, sb.length(), ")");
		sb.append(") values (");
		for (Map.Entry<String, Object> entry : field2NotNullValueMap.entrySet()) {
			Object value = entry.getValue();
			// 判断是否为String类型
			if (value instanceof String) {
				sb.append("'").append(value).append("'");
			} else {
				sb.append(value);
			}
			sb.append(",");
		}

		sb.replace(sb.length() - 1, sb.length(), ")");

		// System.out.println(sb);

		// conn=openConnection();
		// 获取语句对象
		Statement stmt = conn.createStatement();

		int ret = stmt.executeUpdate(sb.toString());
		stmt.close();

		boolean b= ret > 0;
		if(b){
			//将添加记录的id值赋给传入的对象
			
		}
		return b;
	}

	/**
	 * 插入多个对象到表中，其中要求使用事务
	 * 
	 * @param objectList
	 * @param tables
	 * @return
	 */
	public static boolean insert(List<Object> objectList, String... tables) throws Exception {

		assert (null != objectList) : "对象不能为空";
		assert (objectList.size() > 0) : "对象不能为空";

		// 判断连接对象是否有效
		if (null == conn || conn.isClosed()) {
			throw new Exception("连接对象不能为空且不能关闭");
		}

		// insert into table(f1,f2) values (),(),()

		Class<?> clazz = objectList.get(0).getClass();
		// 确定插入的表的名称
		String table = tables.length > 0 ? tables[0] : clazz.getSimpleName();
		// 通过反射类获取所有的getXxx方法（不包括父类的getXxx方法）
		Method[] methods = ReflectUtil.findGetMethods(clazz, "getId");
		// 构建SQL的insert语句
		StringBuilder sb = new StringBuilder();
		sb.append("insert into ").append(leftVoidChar).append(table).append(rightVoidChar).append("( ");
		for (int i = 0; i < methods.length; i++) {
			// 变成小写开头
			String field = StringUtil.toLowerFirstChar(methods[i].getName().substring(3));// 除去get
			sb.append(leftVoidChar).append(field).append(rightVoidChar).append(",");
		}

		sb.deleteCharAt(sb.length() - 1);
		// sb.replace(sb.length()-1, sb.length(), ")");
		sb.append(") values (");
		for (int i = 0; i < methods.length; i++) {
			sb.append("?").append(",");
		}

		sb.replace(sb.length() - 1, sb.length(), ")");

		// System.out.println(sb);
		// 开启一个事务
		conn.setAutoCommit(false);// 表示自已管理事务
		// 预编译的语句对象：它提供了更好的操作性能
		PreparedStatement pstmt = conn.prepareStatement(sb.toString());

		for (Object object : objectList) {

			for (int i = 0; i < methods.length; i++) {
				Object value = methods[i].invoke(object);
				pstmt.setObject(i + 1, value);
			}

			pstmt.addBatch();// 将一个任务加入执行的队列中

		}
		int[] rets = pstmt.executeBatch();

		// 提交一个事务，检查该事务中的所有任务是否都完成了
		try {
			conn.commit();
		} catch (Exception e) {
			conn.rollback();// 将所有任务全部撤销
			return false;
		}

		// 关闭一个事务
		conn.setAutoCommit(true);// 表示不再管理事务

		return rets.length == objectList.size();

	}

	/**
	 * 执行delete语句
	 * 
	 * @param sql
	 *            detete from table where id=xxx or id in()
	 * @return
	 * @throws Exception
	 */
	public static boolean delete(String sql) throws Exception {

		assert (null != sql && !"".equals(sql)) : "SQL不能为空";
		// 判断连接对象是否有效
		if (null == conn || conn.isClosed()) {
			throw new Exception("连接对象不能为空且不能关闭");
		}

		Pattern p = Pattern.compile("^(delete|DELETE) .*$");
		boolean b = p.matcher(sql.trim()).find();
		if (b) {
			conn.setAutoCommit(false);
			// 获取语句对象
			Statement stmt = conn.createStatement();
			int ret = stmt.executeUpdate(sql);
			b = ret > 0;
			try {
				conn.commit();
			} catch (Exception e) {
				conn.rollback();
				b = false;
			} finally {
				stmt.close();
				conn.setAutoCommit(true);
			}

		}
		return b;

	}

	public static boolean delete(String sql,Object...params) throws Exception {
		
		assert (null != sql && !"".equals(sql)) : "SQL不能为空";
		// 判断连接对象是否有效
		if (null == conn || conn.isClosed()) {
			throw new Exception("连接对象不能为空且不能关闭");
		}
		
		Pattern p = Pattern.compile("^(delete|DELETE) .*$");
		boolean b = p.matcher(sql.trim()).find();
		if (b) {
			conn.setAutoCommit(false);
			// 获取语句对象
			PreparedStatement pstmt = conn.prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				pstmt.setObject(i+1, params[i]);
			}
			
			int ret = pstmt.executeUpdate();
			b = ret > 0;
			try {
				conn.commit();//提交事务
			} catch (Exception e) {
				conn.rollback();//回滚事务
				b = false;
			} finally {
				pstmt.close();
				conn.setAutoCommit(true);
			}
			
		}
		return b;
		
	}

	/**
	 * 删除指定id值的记录，表名就是类的简单名称，表的主健列就是类的getId方法的id部分 delete from table where id in
	 * (1,2,3,4,5);
	 * 
	 * @param clazz
	 * @param id
	 * @return
	 */
	public static <T> boolean delete(Class<T> clazz, Serializable... ids) throws Exception {
		boolean b = false;
		String table = clazz.getSimpleName();
		StringBuilder sb = new StringBuilder("delete from ").append(leftVoidChar).append(table).append(rightVoidChar);
		if (ids.length > 0) {
			sb.append(" where ").append(leftVoidChar).append("id").append(rightVoidChar).append(" in ( ");
			for (Serializable id : ids) {
				sb.append(id).append(",");
			}
			sb.replace(sb.length() - 1, sb.length(), ")");
		}
		// 判断连接对象是否有效
		if (null == conn || conn.isClosed()) {
			throw new Exception("连接对象不能为空且不能关闭");
		}

		conn.setAutoCommit(false);
		// 获取语句对象
		Statement stmt = conn.createStatement();
		int ret = stmt.executeUpdate(sb.toString());
		b = ret > 0;
		try {
			conn.commit();
		} catch (Exception e) {
			conn.rollback();
			b = false;
		} finally {
			stmt.close();
			conn.setAutoCommit(true);
		}

		return b;

	}

	/**
	 * 执行update语句
	 * 
	 * @param sql
	 * @return
	 * @throws Exception
	 */
	public static boolean update(String sql,Object...params) throws Exception {
		assert (null != sql && !"".equals(sql)) : "SQL不能为空";
		// 判断连接对象是否有效
		if (null == conn || conn.isClosed()) {
			throw new Exception("连接对象不能为空且不能关闭");
		}

		Pattern p = Pattern.compile("^(update|UPDATE) .*$");
		boolean b = p.matcher(sql.trim()).find();
		if (b) {
			conn.setAutoCommit(false);
			// 获取带参数的语句对象
			PreparedStatement pstmt = conn.prepareStatement(sql);
			
			for(int i=0;i<params.length;i++){
				pstmt.setObject(i+1, params[i]);
			}
			
			int ret = pstmt.executeUpdate();
			b = ret > 0;
			try {
				conn.commit();
			} catch (Exception e) {
				System.out.println(sql);
				System.out.println(e.getMessage());
				conn.rollback();
				b = false;
			} finally {
				pstmt.close();
				conn.setAutoCommit(true);
			}

		}
		return b;
	}

	public static boolean update(Object bean, String... tables) throws Exception {
		assert (null != bean) : "对象不能为空";
		// 判断连接对象是否有效
		if (null == conn || conn.isClosed()) {
			throw new Exception("连接对象不能为空且不能关闭");
		}

		Class<? extends Object> clazz = bean.getClass();
		String table = tables.length > 0 ? tables[0] : clazz.getSimpleName();
		StringBuilder sb = new StringBuilder("update ");
		sb.append(leftVoidChar).append(table).append(rightVoidChar).append(" set ");
		List<Object> valueList = new ArrayList<>();
		// 构建形如：update table set f1=?,f2=? where id=?语句
		Method[] methods = ReflectUtil.findGetMethods(clazz, "getId");
		for (Method method : methods) {
			// 变成小写开头
			String field = StringUtil.toLowerFirstChar(method.getName().substring(3));// 除去get
			Object value = method.invoke(bean);
			if (null != value) {// 当该字段不为空时，才需要更新
				sb.append(leftVoidChar).append(field).append(rightVoidChar).append("=?,");// field=?,
				valueList.add(value);
			}
		}
		sb.deleteCharAt(sb.length() - 1);
		sb.append(" where ").append(leftVoidChar).append("id").append(rightVoidChar).append("=?");

		PreparedStatement pstmt = conn.prepareStatement(sb.toString());
		// 替换set和where语句中的?
		Method m = ReflectUtil.findGetMethod(clazz, "id");
		valueList.add(m.invoke(bean));// 加入id字段的值

		for (int i = 0; i < valueList.size(); i++) {
			pstmt.setObject(i + 1, valueList.get(i));
		}

		conn.setAutoCommit(false);

		int ret = pstmt.executeUpdate();

		boolean b = false;
		b = ret > 0;
		try {
			conn.commit();
		} catch (Exception e) {
			conn.rollback();
			b = false;
		} finally {
			pstmt.close();
			conn.setAutoCommit(true);
		}

		return b;
	}

	/**
	 * 查询一行的列值列表数据 select id as 编号 from table
	 * 
	 * @param sql
	 *            select * from table or select id,name from table where id=1 or
	 *            select * from table where id=?
	 * @return row-->(张三,男,18)->map(key(列名称)-->value(列的值))
	 */
	public static List<Map<String, Object>> selectAll(String sql, Object... params) throws Exception {

		assert (null != sql && !"".equals(sql)) : "SQL语句不能为空";
		// 判断连接对象是否有效
		if (null == conn || conn.isClosed()) {
			throw new Exception("连接对象不能为空且不能关闭");
		}

		List<Map<String, Object>> list = new ArrayList<>();

		PreparedStatement pstmt = conn.prepareStatement(sql);
		for (int i = 0; i < params.length; i++) {
			pstmt.setObject(i + 1, params[i]);
		}
		// 对象查询操作不需事务
		conn.setAutoCommit(true);
		ResultSet rs = pstmt.executeQuery();// 获取结果集对象

		ResultSetMetaData rsmd = rs.getMetaData();// 获取查询语句的结构信息：1、列的名称，2，列的个数
		int cols = rsmd.getColumnCount();
		Map<String, Integer> columnName2IndexMap = new HashMap<>(cols);
		for (int i = 0; i < cols; i++) {
			columnName2IndexMap.put(rsmd.getColumnName(i + 1), i + 1);
		}

		while (rs.next()) {// 是否有下一行查询数据（记录）
			// 获取当前行的数据
			Map<String, Object> rowMap = new HashMap<>(cols);
			for (Map.Entry<String, Integer> entry : columnName2IndexMap.entrySet()) {
				String name = entry.getKey();
				Integer index = entry.getValue();
				Object value = rs.getObject(index);
				rowMap.put(name, value);
			}

			list.add(rowMap);

		}

		return list;
	}

	public static Map<String, Object> selectOne(String sql, Object... params) throws Exception {
		List<Map<String, Object>> rowList = selectAll(sql, params);
		if (rowList.size() > 0) {
			return rowList.get(0);
		}
		return new HashMap<String, Object>();
	}

	/**
	 * 将map属性映射到java bean：约定：map的key=bean.getXxxx中的xxxx
	 * @param clazz
	 * @param properties
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static <T> T mapToBean(Class<?> clazz, Map<String, Object> properties) throws Exception {

		// 获取当前行的数据
		T o =(T)clazz.newInstance();// 要求类有一个无参数的构造方法
		for (Map.Entry<String, Object> entry : properties.entrySet()) {
			String name = entry.getKey();//对应bean的getXxxx中的xxxx属性名称
			Object value = entry.getValue();
			Method m = ReflectUtil.findSetMethod(clazz, name);
			if (null != m) {
				m.invoke(o, value);// -->setXxx(value)
			}
		}
		return o;

	}

	public static <T> T mapToBean(T bean, Map<String, Object> properties) throws Exception {
		
		// 获取当前行的数据
		for (Map.Entry<String, Object> entry : properties.entrySet()) {
			String name = entry.getKey();//对应bean的getXxxx中的xxxx属性名称
			Object value = entry.getValue();
			Method m = ReflectUtil.findSetMethod(bean.getClass(), name);
			if (null != m) {
				m.invoke(bean, value);// -->setXxx(value)
			}
		}
		return bean;
		
	}

	/**
	 * 查询指定的对象T列表 将每一行数据--->一个对象 约定： 1、类的名称与表的名称对应。2、对象的getXxx的Xxx写小xxx对应数据表的列名称
	 * 。3、对象的id对象表的主键列。4、类有一个无参数的构造方法
	 * 
	 * @param clazz
	 * @param whereClase
	 *            --> id=? or id=1
	 * @return
	 */
	public static <T> List<T> selectAll(Class<T> clazz, String whereClase, Object... params) throws Exception {
		// 判断连接对象是否有效
		if (null == conn || conn.isClosed()) {
			throw new Exception("连接对象不能为空且不能关闭");
		}

		// 根据类的信息生成select语句
		StringBuilder sb = new StringBuilder("select * from ").append(leftVoidChar).append(clazz.getSimpleName())
				.append(rightVoidChar);

		List<T> list = new ArrayList<>();

		if (null != whereClase && !"".equals(whereClase)) {
			sb.append(" where ").append(whereClase);
		}

		PreparedStatement pstmt = conn.prepareStatement(sb.toString());
		for (int i = 0; i < params.length; i++) {

			if (params[i] instanceof Object[]) {// 判断第一个可选参数是不是一个数组
				Object[] args = (Object[]) params[i];
				for (int j = 0; j < args.length; j++) {
					pstmt.setObject(j + 1, args[j]);
				}
			} else {
				pstmt.setObject(i + 1, params[i]);
			}
		}
		// 对象查询操作不需事务
		conn.setAutoCommit(true);
		ResultSet rs = pstmt.executeQuery();// 获取结果集对象

		ResultSetMetaData rsmd = rs.getMetaData();// 获取查询语句的结构信息：1、列的名称，2，列的个数
		int cols = rsmd.getColumnCount();
		Map<String, Integer> columnName2IndexMap = new HashMap<>(cols);
		for (int i = 0; i < cols; i++) {
			columnName2IndexMap.put(rsmd.getColumnName(i + 1), i + 1);
		}

		while (rs.next()) {// 是否有下一行查询数据（记录）
			// 获取当前行的数据
			T o = clazz.newInstance();// 要求类有一个无参数的构造方法
			for (Map.Entry<String, Integer> entry : columnName2IndexMap.entrySet()) {
				String name = entry.getKey();
				Integer index = entry.getValue();
				Object value = rs.getObject(index);
				Method m = ReflectUtil.findSetMethod(clazz, name);
				if (null != m) {
					m.invoke(o, value);// -->setXxx(value)
				}
			}
			list.add(o);
		}

		return list;
	}

	public static <T> List<T> selectAll(Class<T> clazz) throws Exception {
		return selectAll(clazz, null);
	}

	public static <T> T selectOne(Class<T> clazz, String whereClase, Object... params) throws Exception {
		List<T> list = selectAll(clazz, whereClase, params);
		if (list.size() > 0) {
			return list.get(0);
		} else {
			return null;
		}
	}

	public static <T> T selectOne(Class<T> clazz) throws Exception {
		List<T> list = selectAll(clazz, null);
		if (list.size() > 0) {
			return list.get(0);
		} else {
			return null;
		}
	}

	/**
	 * 清空数据表，将自动递增字段重置从1开始
	 * 
	 * @param clazz
	 * @return
	 */
	public static <T> boolean truncate(Class<T> clazz) throws Exception {

		String sql = "truncate table " + clazz.getSimpleName();
		// 判断连接对象是否有效
		if (null == conn || conn.isClosed()) {
			throw new Exception("连接对象不能为空且不能关闭");
		}

		// 获取语句对象
		Statement stmt = conn.createStatement();
		boolean b = stmt.execute(sql);
		stmt.close();

		return b;
	}

	/**
	 * 判断某个字段是否存在于数据表中
	 * 
	 * @param clazz
	 * @param field
	 * @param value
	 * @return
	 * @throws Exception
	 */
	public static <T> boolean exists(Class<T> clazz, String field, Object value) throws Exception {

		StringBuilder sb = new StringBuilder();
		sb.append("select").append(leftVoidChar).append(field).append(rightVoidChar).append(" from ")
				.append(leftVoidChar).append(clazz.getSimpleName()).append(rightVoidChar).append(" where ")
				.append(leftVoidChar).append(field).append(rightVoidChar).append("=?");
		/*
		 * if (value instanceof String) {
		 * sb.append("'").append(value).append("'"); }else{ sb.append(value); }
		 */
		// 判断连接对象是否有效
		if (null == conn || conn.isClosed()) {
			throw new Exception("连接对象不能为空且不能关闭");
		}

		PreparedStatement pstmt = conn.prepareStatement(sb.toString());
		pstmt.setObject(1, value);
		ResultSet rs = pstmt.executeQuery();
		boolean b = rs.next();

		pstmt.close();

		return b;

	}
	
	public static long sumOf(String field,String table) throws Exception{
		StringBuilder sb=new StringBuilder();
		sb.append("select ");
		sb.append("sum(").append(leftVoidChar).append(field).append(rightVoidChar).append(") as sum");
		sb.append(" from ").append(leftVoidChar).append(table).append(rightVoidChar);
		Map<String,Object> rowMap=selectOne(sb.toString());
		BigDecimal bd=(BigDecimal)rowMap.get("sum");
		if(null==bd){
			return 0;
		}else{
			return bd.longValue();
		}
		
	}
	public static long countOf(String field, String table)throws Exception {
		StringBuilder sb=new StringBuilder();
		sb.append("select ");
		sb.append("count(").append(leftVoidChar).append(field).append(rightVoidChar);
		sb.append(") as cnt");
		sb.append(" from ").append(leftVoidChar).append(table).append(rightVoidChar);
		Map<String,Object> rowMap=selectOne(sb.toString());
		Long l=(Long)rowMap.get("cnt");
		if(null==l){
			return 0;
		}
		return l;
	}

	public static long countOf(String field, String table,String whereClase,Object...params)throws Exception {
		StringBuilder sb=new StringBuilder();
		sb.append("select ");
		sb.append("count(").append(leftVoidChar).append(field).append(rightVoidChar).append(") as cnt");
		sb.append(" from ").append(leftVoidChar).append(table).append(rightVoidChar);
		sb.append(" where ").append(whereClase);
		Map<String,Object> rowMap=selectOne(sb.toString(),params);
		Long l=(Long)rowMap.get("cnt");
		if(null==l){
			return 0;
		}
		return l;
	}
	

}
